﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Global
{
    public class EventBus
    {
        private static readonly Dictionary<Type, List<Delegate>> _handlers =new Dictionary<Type, List<Delegate>>();

        private static readonly Dictionary<string, List<Action<object>>> _eventSubscriptions = new Dictionary<string, List<Action<object>>>();

        public static void Subscribe<TEvent>(Action<TEvent> handler)
        {
            var eventType = typeof(TEvent);
            if (!_handlers.ContainsKey(eventType))
            {
                _handlers[eventType] = new List<Delegate>();
            }
            _handlers[eventType].Add(handler);
        }

        public static void Publish<TEvent>(TEvent eventToPublish)
        {
            var eventType = typeof(TEvent);
            if (_handlers.TryGetValue(eventType, out var handlers))
            {
                foreach (var handler in handlers)
                {
                    ((Action<TEvent>)handler)(eventToPublish);
                }
            }
        }

        #region 事件总线.弱类型
        public static void Subscribe(string eventName, Action<object> handler)
        {
            if (!_eventSubscriptions.ContainsKey(eventName))
            {
                _eventSubscriptions[eventName] = new List<Action<object>>();
            }

            _eventSubscriptions[eventName].Add(handler);
        }

        public static void Unsubscribe(string eventName, Action<object> handler)
        {
            if (_eventSubscriptions.ContainsKey(eventName))
            {
                _eventSubscriptions[eventName].Remove(handler);
            }
        }

        public static void Publish(string eventName, object data)
        {
            if (_eventSubscriptions.TryGetValue(eventName, out var handlers))
            {
                foreach (var handler in handlers.ToList())
                {
                    try
                    {
                        handler(data);
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
        }
        #endregion

    }
}
